#ifndef __LIST_H_
#define __LIST_H_
/**
 * Desc: 一个简单的单向链表
 * Auth: 张宇飞
 * Date: 2014-06-19    
 */
#include "config.h"

#ifdef __cplusplus
extern "C" {
#endif

/*********************| 数据结构声明 |*********************/
struct node_t;
/* 链表结构 */
typedef struct {
	size_t		size;	// 链表元素个数
	struct node_t*	head;	// 链表头
} list_t;

typedef struct {
	size_t		pos;	// 数据在链表中的索引位置
	void*		datare;	// 数据在链表中的地址引用,可以直接修改数据
} findRes_t;

/* 比较两个数据的大小 返回0 表示相等，1表示 pa > pb, -1表示 pa < pb */
typedef int (*node_data_cmp)(void* pa, void* pb);

/* 用来处理节点数据 */
typedef void (*node_data_handle)(void* pdata);
#define free_node_data		node_data_handle

/**
 * 用于遍历链表的时候处理链表数据
 * 1继续执行
 * 2删除当下元素后继续执行
 * 返回其它表示立刻中断执行
 **/
typedef int (*node_data_foreach)(void** datare, void* ctlflag);
/*********************| 外部接口声明 |*********************/

extern CSB_DLL void		list_buf_init();
/**
 * @brief 创建一个链表结构
 */
#define list_init(plist)	memset((plist), 0, sizeof(list_t))
extern CSB_DLL list_t*		list_new();

/**
 * @brief 遍历链表并执行func处理链表的数据
 */
extern CSB_DLL int		list_foreach(list_t* pal, node_data_foreach func, void* ctlflag);

/**
 * @brief 清零链表,将清除链表的所有数据
 * @func 传递NULL将不对节点中的数据做处理
 */
extern CSB_DLL int 		list_clear(list_t* pal, free_node_data func);

/**
 * @brief 释放一个链表
 */
#define list_free(pal, func)	{list_clear(pal, func); CSB_SAFE_FREE(pal);}

/**
 * @brief 向链表中的某个索引位置插入数据
 * @istail 0表示向中间位置插入，需要给出明确的pos值
 * istail 非零表示向尾部插入，pos参数将被忽略
 */
extern CSB_DLL size_t		list_insert(list_t* pal, void* data, size_t pos, const int istail);

/**
 * @brief 获取元素
 * @out 获得节点的数据引用(可用来直接修改节点数据)
 */
extern CSB_DLL size_t		list_get(list_t* pal, size_t pos, void** out);

/**
 * @brief 查找元素
 * @func 传递NULL将使用默认的数值比较
 * @return NULL 表示找不到或者出现错误,找到将返回满足条件的第一个数据
 */
extern CSB_DLL findRes_t*	list_find(list_t* pal, void* data, node_data_cmp func);

/**
 * @brief 删除指定位置的元素, 返回那个位置的元素值
 * @srcdata 是输出参数
 */
extern CSB_DLL size_t		list_del(list_t* pal, size_t pos, void** srcdata);

/**
 * @brief 查找并删除节点，然后返回原始数据
 * @return ERR_FINIAL 表示找不到
 *
 */
extern CSB_DLL size_t		list_finddel(list_t* pal, void* data, node_data_cmp func, void** srcdata);

#ifdef __cplusplus
} /* end extern C */
#endif

#endif /* end of include guard: __LIST_H_ */
